﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <utility>
#include "mylist.h"
#include "mystring.h"

int main()
{
	txp::list <pair<txp::string, int>> lt;
	pair<txp::string, int> kv("苹果", 1);

	//传左值，跟push_back效果一样
	lt.emplace_back(kv);
	cout << "**************************************" << endl;

	//传右值，跟push_back效果一样
	lt.emplace_back(move(kv));
	cout << "**************************************" << endl;

	//这里是多参数传参
	lt.emplace_back("苹果", 1);
	cout << "**************************************" << endl;
	
	return 0;
}

//int main()
//{
//	txp::list <pair<txp::string, int>> lt;
//	pair<txp::string, int> kv("苹果", 1);
//
//	//传左值，跟push_back效果一样
//	lt.emplace_back(kv);
//	cout << "**************************************" << endl;
//
//	//传右值，跟push_back效果一样
//	lt.emplace_back(move(kv));
//	cout << "**************************************" << endl;
//
//	//这里是多参数传参
//	lt.emplace_back("苹果", 1);
//	cout << "**************************************" << endl;
//	//push_back无法直接传参，需要{}进行隐式类型转换
//	lt.push_back({ "苹果",1 });
//	//相对应的，emplace_back是不支持使用{}进行转换的
//	cout << "**************************************" << endl;
//
//	return 0;
//}


//int main()
//{
//	list<txp::string> lt;
//	txp::string s1("111111");
//
//	//传左值，跟push_back效果一样，走拷贝构造
//	lt.emplace_back(s1);
//	cout << "**************************************" << endl;
//
//	//传右值，跟push_back效果一样，走移动构造
//	lt.emplace_back(move(s1));
//	cout << "**************************************" << endl;
//
//	//这里效果就和push_back不一样
//	lt.emplace_back("2222222");
//	cout << "**************************************" << endl;
//	//对比一下运行结果就知道了
//	lt.push_back("333333333");
//	cout << "**************************************" << endl;
//
//	return 0;
//}
//// 本质可以理解为编译器编译时，包的扩展模式
//// 将上面的函数模板扩展实例化为下面的函数
//// 是不是很抽象，C++11以后，只能说委员会的大佬设计语法思维跳跃得太厉害
//void Print(int x, string y, double z)
//{
//	Arguments(GetArgs(x), GetArgs(y), GetArgs(z));
//}
// 
//
////获取每个参数
//template<class T>
//const T& GetArgs(const T& x)
//{
//	cout << x << " ";
//	return x;
//}
//
////可变参数模板
//template<class ...Args>
//void Arguments(Args... args)
//{
//	cout << endl;
//}
//
////可变参数模板
//template<class ...Args>
//void Print(Args&&... args)
//{
//	//利用参数的特殊性，
//	//在传参前调用GetArgs将每个参数打印出来
//	Arguments(GetArgs(args)...);
//}
//
//int main()
//{
//	double x = 2.2;
//	Print(1);
//	Print(1, string("xxxxx"));
//	Print(1.1, string("xxxx"), x);
//
//	return 0;
//}

////递归的终止函数，当参数包是0个时匹配这个函数
//void ShowList()
//{
//	cout << endl;
//}
//
//template<class T,class ...Args>
//void ShowList(T x, Args... args)
//{
//	//args是N个参数的参数包
//	//调用ShowList，参数包的第一个传给x，剩下的N-1个传给第二个参数包
//	cout << x << " ";
//	ShowList(args...);
//}
//
////可变参数模板
//template<class ...Args>
//void Print(Args&&... args)
//{
//	ShowList(args...);//注意传参时(...)是放在参数包后面
//}
//
//
//int main()
//{
//	double x = 2.2;					
//	Print(1);					
//	Print(1, string("xxxxx"));		
//	Print(1.1, string("xxxx"), x);
//
//	return 0;
//}

////原理1：编译本质这里会结合引用折叠规则实例化出以下四个函数
//void Print();
//void Print(int&& arg1);
//void Print(int&& arg1, string&& arg2);
//void Print(double&& arg1, string&& arg2, double& arg3);
//
//
//
//// 原理2：更本质去看没有可变参数模板，
//// 我们实现出这样的多个函数模板才能支持这里的功能，
//// 有了可变参数模板，我们进⼀步被解放，
//// 他是类型泛化基础上叠加数量变化，让我们泛型编程更灵活。
//void Print();
//
//template <class T1>
//void Print(T1&& arg1);
//
//template <class T1, class T2>
//void Print(T1 && arg1, T2 && arg2);
//
//template <class T1, class T2, class T3>
//void Print(T1&& arg1, T2&& arg2, T3&& arg3);
//
//
////可变参数模板
//template<class ...Args>
//void Print(Args&&... args)
//{
//	cout << sizeof...(args) << endl;
//}
//
//int main()
//{
//	double x = 2.2;
//	Print();						//保留有0个模板参数
//	Print(1);						//包里有1个模板参数
//	Print(1, string("xxxxx"));		//包里有2个模板参数
//	Print(1.1, string("xxxx"), x);	//包里有3个模板参数
//
//	return 0;


//#include <iostream>
//#include <utility>
//using namespace std;
//
//void Fun(int& x) { cout << "左值引用" << endl; }
//void Fun(const int& x) { cout << "const左值引用" << endl; }
//void Fun(int&& x) { cout << "右值引用" << endl; }
//void Fun(const int&& x) { cout << "const右值引用" << endl; }
//
////万能引用
//template<class T>
//void Function(T&& t)
//{
//	//forward完美转发
//	Fun(forward<T>(t));
//}
//
//int main()
//{
//	//10是右值，模版实例化为void Function(int&& t)
//	Function(10);//打印出的地址不同，佐证了T为int类型
//
//	//a是左值，模板实例化为void Function(int& t)
//	int a;
//	Function(a);
//
//	//move(a)是右值，模板实例化为void Function(int&& t)
//	Function(move(a));
//
//	//b是const左值，模板实例化为void Function(const int& t)
//	const int b = 1;
//	Function(b);
//
//	//move(b)是const右值，模板实例化为void Function(const int&& t)
//	Function(move(b));
//
//	return 0;
//}

//template<class T>
//void Function(T&& t)
//{
//	int a = 0;
//	T x = a;
//	//x++;  const无法修改
//
//	//观察地址判断x是不是a的引用别名
//	cout << &a << endl;
//	cout << &x << endl << endl;
//}
//
//int main()
//{
//	//b是const左值，推导出T为const int&，模板实例化为void Function(const int& t)
//	const int b = 1;//因为T是const修饰，所以不能x++
//	Function(b);//然后地址依旧相同，佐证T为const int&类型
//
//	//move(b)是const右值，推导出T为const int，模板实例化为void Function(const int&& t)
//	Function(move(b));//同样，x不能修改，地址不同，佐证T为const int类型
//
//	return 0;
//}

//int main()
//{
//	//10是右值，推导出T为int，模版实例化为void Function(int&& t)
//	Function(10);//打印出的地址不同，佐证了T为int类型
//
//	//a是左值，推导出T为int&，模板实例化为void Function(int& t)
//	int a;
//	Function(a);//打印出的地址相同，佐证了T为int&类型
//
//	//move(a)是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(move(a));//打印出的地址不同，佐证了T为int类型
//
//	return 0;
//}

////左值引用
//template<class T>
//void f1(T& x)
//{}

//万能引用
//传左值引用折叠为左值引用
//传右值引用折叠为右值引用
//template<class T>
//void f2(T&& x)
//{}
//
//int main()
//{
//	int n = 0;
//
//	f1<int>(n);//没有折叠->实例化为void f1(int& x)
//	//f1(0);报错
//
//	f1<int&>(n);//折叠->实例化为void f1(int& x);
//	//f1<int&>(0);报错
//
//	f1<int&&>(n);//折叠->实例化为void f1(int& x);
//	//f1<int&&>(0);报错
//
//	//折叠->实例化为void f1(const int& x);
//	f1<const int&>(n);
//	f1<const int&>(0);
//
//	//折叠->实例化为void f1(const int& x);
//	f1<const int&&>(n);
//	f1<const int&&>(0);
//
//	//------------------------------------
//
//	f2(n);
//	f2<int>(0);//没有折叠->实例化为void f2(int&& x);
//
//	f2<int&>(n);//折叠->实例化为void f2(int& x);
//	f2(0);
//
//	f2(n);
//	f2<int&&>(0);//折叠->实例化为void f2(int&& x);
//
//	//折叠->实例化为void f2(const int& x);
//	f1<const int&>(n);
//	f1<const int&>(0);
//
//	f2(n);
//	f2<const int&&>(0);//折叠->实例化为void f2(const int&& x);
//
//	return 0;
//}

//int main()
//{
//	typedef int& lref;
//	typedef int&& rref;
//	int n = 0;
//
//	//引用折叠
//	lref& r1 = n;	//r1的类型是 int&
//	lref&& r2 = n;	//r2的类型是 int&
//	rref& r3 = n;	//r3的类型是 int&
//	rref&& r4 = 1;	//r4的类型是 int&&
//
//	return 0;
//}


//int main()
//{
//	typedef int& lref; //重命名int的左值引用
//
//	int i = 0;
//	lref&& r = i; //不会报错
//
//	return 0;
//}

//#include <utility>
//#include "mylist.h"
//#include "mystring.h"
//
//int main()
//{
//	txp::list<txp::string> lt;
//
//	txp::string s1("xxxxxxxxxxx");
//	lt.push_back(s1);
//	cout << "*************************************" << endl;
//
//	lt.push_back(txp::string("11111111"));
//	cout << "*************************************" << endl;
//
//	lt.push_back("22222222");
//	cout << "*************************************" << endl;
//
//	lt.push_back(move(s1));
//	cout << "*************************************" << endl;
//
//	return 0;
//}

//int main()
//{
//	txp::string ret;
//	ret = txp::addStrings("500", "20");
//	cout << endl << ret.c_str() << endl;
//
//	return 0;
//}


//int main()
//{
//	//普通构造
//	txp::string s1("xxxxxx");
//
//	//拷贝构造
//	txp::string s2 = s1;
//
//	//构造+移动构造，编译器优化后变为直接构造
//	txp::string s3 = txp::string("111111");
//
//	//移动构造
//	txp::string s4(move(s1));
//
//	cout << endl << "*****************************" << endl << endl;
//
//	return 0;
//}


//#include <iostream>
//#include <string>
//#include <vector>
//#include <utility>
//using namespace std;
//
////计算数字字符串num1和numl的和
//class Solution1
//{
//public:
//    //传值返回需要拷贝
//    string addStrings(string num1, string num2) 
//    {
//        string str;
//        int end1 = num1.size() - 1, end2 = num2.size() - 1;
//
//        //进位
//        int next = 0;
//        while (end1 >= 0 || end2 >= 0)
//        {
//            int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
//            int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
//            int ret = val1 + val2 + next;
//            next = ret / 10;
//            ret = ret % 10;
//            str += ('0' + ret);
//        }
//        if (next == 1)
//            str += '1';
//
//        reverse(str.begin(), str.end());
//        return str;
//    }
//};
//
////打印杨辉三角
//class Solution2 {
//public:
//    // 这里的传值返回拷贝代价就太大了
//    vector<vector<int>> generate(int numRows)
//    {
//        vector<vector<int>> vv(numRows);
//        for (int i = 0; i < numRows; ++i)
//        {
//            vv[i].resize(i + 1, 1);
//        }
//        for (int i = 2; i < numRows; ++i)
//        {
//            for (int j = 1; j < i; ++j)
//            {
//                vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];
//            }
//        }
//
//        return vv;
//    }
//};
//
//int main()
//{
//    cout << Solution1().addStrings("100", "200") << endl;
//
//    auto ret = Solution2().generate(3);
//    for (auto& e : ret)
//    {
//        for (auto& n : e)
//        {
//            cout << n << " ";
//        }
//        cout << endl;
//    }
//
//    return 0;
//}

//string& f()
//{
//	string s("xxxxx");
//	return s;
//}
//
//int main()
//{
//	string& ret = f();
//	cout << ret << endl;
//
//	return 0;
//}

//void f(int& x)
//{
//	cout << "左值引用重载 f(int& x)" << endl;
//}
//
//void f(const int& x)
//{
//	cout << "const左值引用重载 f(const int& x)" << endl;
//}
//
//void f(int&& x)
//{
//	cout << "右值引用重载 f(int&& x)" << endl;
//}
//
//int main()
//{
//	int i = 1;
//	const int ci = 2;
//
//	f(i);	//调用f(int x)
//	f(ci);	//调用f(const int& x)
//	f(3);	//调用f(int&& x)
//	f(move(i));	//调用f(int&& x)
//
//	cout << endl;
//
//	//右值引用本身属性是左值
//	int&& rr1 = 4;
//	f(rr1);	//调用f(int& x);
//	f(move(rr1)); //调用f(int&& x);
//
//	return 0;
//}

//int main()
//{
//	//可以延长临时对象或者匿名对象的生命周期
//	const string& r1 = string("xxxxx");
//	string&& rr1 = string("1111111");
//
//	
//	//r1 += "1111";//这里const左值引用不能修改
//	rr1 += "xxxx";//右值引用是支持修改的
//	cout << rr1 << endl;
//
//	return 0;
//}

//int main()
//{
//	//右值引用本身（rr1）是左值属性
//	string&& rr1 = string("xxxxxxxx");
//	cout << &rr1 << endl;
//
//	//所以如果还要对rr1取别名,可以用move强转一下,或者const左值引用
//	const string& r1 = rr1;
//	string&& rr2 = move(rr1);
//
//	return 0;
//}



//#include <utility>
//using namespace std;

//int main()
//{
//	//左值：可以取地址
//	int* p = new int(1);
//	int b = 1;
//	const int c = b;
//	*p = 10;
//	string s("xxxxxxx");
//
//	//可以用move将左值属性转为右值，再用右值引用取别名
//	int*&& rr1 = move(p);
//	int&& rr2 = move(b);
//	const int&& rr3 = move(c);
//	int&& rr4 = move(*p);
//	string&& rr5 = move(s);
//	string&& rr6 = (string&&)s;//这样也能侧面证明move本质是一个强制类型转换
//
//	return 0;
//}

//int main()
//{
//	//const左值引用给右值取别名
//	double x = 1.1, y = 2.2;
//	const int& r1 = 10;
//	const double& r2 = x + y;
//	const double& r3 = fmin(x, y);
//	const string& r4 = string("111111");
//
//	return 0;
//}

//int main()
//{
//	//左值：可以取地址
//	//以下的p、b、c、*p、s、s[0]都是常见的左值
//	int* p = new int(1);
//	int b = 1;
//	const int c = b;
//	*p = 10;
//	string s("xxxxxxx");
//	s[0] = '1';
//
//	//左值引用给左值取别名
//	int*& r1 = p;
//	int& r2 = b;
//	const int& r3 = c;
//	int& r4 = *p;
//	string& r5 = s;
//	char& r6 = s[0];
//
//
//	//右值引用给右值取别名
//	double x = 1.1, y = 2.2;
//	int&& rr1 = 10;
//	double&& rr2 = x + y;
//	double&& rr3 = fmin(x, y);
//	string&& rr4 = string("111111");
//
//	return 0;
//}

//int main1()
//{
//	//左值：可以取地址
//	//以下的p、b、c、*p、s、s[0]都是常见的左值
//	int* p = new int(1);
//	int b = 1;
//	const int c = b;
//	*p = 10;
//	string s("xxxxxxx");
//	s[0] = '1';
//
//	//左值都可以取地址
//	cout << p << endl;
//	cout << &b << endl;
//	cout << &c << endl;
//	cout << &(*p) << endl;
//	cout << &s << endl;
//	cout << (void*)&s[0] << endl;
//
//
//	//右值：不可以取地址
//	double x = 1.1, y = 2.2;
//	//以下的10、x+y、fmin(x,y)、string("111111")都是一些常见的右值
//	10;
//	x + y;
//	fmin(x, y);
//	string("111111");
//
//	//无法取地址，会报错
//	/*cout << &10 << endl;
//	cout << &(x+y) << endl;
//	cout << &(fmin(x, y)) << endl;
//	cout << &string("11111") << endl;*/
//
//	return 0;
//}

//#include <iostream>
//#include <vector>
//#include <list>
//#include <map>
//using namespace std;
//
//int main()
//{
//	auto it = { 1,2,3,4,5,6,7 };
//	for (auto& e : it)
//	{
//		cout << e << " ";
//	}
//	cout << endl << typeid(it).name() << endl << endl;
//
//	//直接使用initializer_list进行初始化列表赋值构造
//	vector<int> v1(it);
//	list<int> l1({ 1,2,3,4,5,6 });
//	map<int, int> m1({ {1,1},{2,2},{3,3 } });
//
//	return 0;
//}

//#include <iostream>
//#include <vector>
//using namespace std;
//
//class Date
//{
//public:
//    Date(int year = 1, int month = 1, int day = 1)
//        :_year(year)
//        , _month(month)
//        , _day(day)
//    {
//        cout << "Date(int year, int month, int day)" << endl;
//    }
//    Date(const Date& d)
//        :_year(d._year)
//        , _month(d._month)
//        , _day(d._day)
//    {
//        cout << "Date(const Date& d)" << endl;
//    }
//private:
//    int _year;
//    int _month;
//    int _day;
//};
//
//int main()
//{
//    //可以省略=
//    int x1{ 1 };
//    Date d1{ 2025,9,1 };
//    const Date& d2{ 2024,9,1 };
//
//    //比起有名对象和匿名对象传参，这里直接使用{}更方便
//    vector<Date> v1;
//    v1.push_back({ 2025,10,1 });
//
//    return 0;
//}

//int main()
//{
//    //c++11{}支持内置类型
//    //不过也没人这么用
//    int x = { 1 };
//
//    //自定义类型
//    //这里本质是用 {2025,9,1} 构造一个临时对象
//    //再用临时对象拷贝构造 d1
//    //编译器合二为一优化成直接构造，也就是没有临时对象和拷贝构造了
//    Date d1 = { 2025, 9, 1 };
//
//    //那么这里就是引用临时对象了
//    const Date& d2 = { 2024, 9, 1 };
//
//    //需要注意的是c++98支持单参数构造，也可以不用{}
//    //前提是得有默认构造
//    Date d3 = { 2025 };
//    Date d4 = 2024;
//
//    return 0;
//}






//struct Point
//{
//	int _x;
//	int _y;
//};
//
//int main()
//{
//	c++98支持的{}初始化
//	int array1[] = { 1, 2, 3, 4, 5 };
//	int array2[5] = { 0 };
//	Point p = { 1, 2 };
//
//	return 0;
//}